//
// Created by limo on 2025/9/26.
//

#pragma once

#include <vector>
#include <string>
#include <boost/asio.hpp>

namespace net {
    using Buffer = std::vector<uint8_t>;
    /**
     * @brief 消息编解码器接口，负责将字节流解析为完整消息（解码）
     * 并将消息封装为带头部的数据包（编码）。
     */
    class MessageCodec {
    public:
        virtual ~MessageCodec() = default;

        /**
         * @brief 尝试解析数据流中的完整消息。
         * @param bytes_in 本次收到的原始字节数据指针。
         * @param length 本次收到的字节长度。
         * @param messages_out 解析出的完整消息体列表。
         * @return bool 解析是否成功（用于致命错误判断）。
         */
        virtual bool decode(const uint8_t* bytes_in, size_t length, std::vector<Buffer>& messages_out) = 0;

        /**
         * @brief 封装消息体，添加协议头部等，准备发送。
         * @param message_body 待发送的原始消息体。
         * @return Buffer 包含协议头的完整数据包。
         */
        virtual Buffer encode(const Buffer& message_body) = 0;

        /**
         * @brief 清除内部缓冲区状态（例如连接重置时）。
         */
        virtual void reset() = 0;
    };

    class SimpleMessageCodec : public MessageCodec {
    public:
        static constexpr size_t HEADER_SIZE = 4;

        bool decode(const uint8_t* bytes_in, size_t length, std::vector<Buffer>& messages_out) override {
            // 1. 将新数据追加到内部缓冲区
            size_t old_size = m_messageBuffer.size();

            // **【修正】使用 resize 和 memcpy 追加数据**
            m_messageBuffer.resize(old_size + length);
            // 从 bytes_in (char*) 复制到 m_messageBuffer.data() (uint8_t*)
            std::memcpy(m_messageBuffer.data() + old_size, bytes_in, length);

            // 2. 解析循环 (逻辑不变，但指针获取方式改变)
            size_t current_pos = 0;
            while (m_messageBuffer.size() - current_pos >= HEADER_SIZE) {

                // 提取长度头部（必须从 uint8_t* 转换到 char* 进行 memcpy）
                uint32_t net_length;
                std::memcpy(&net_length, m_messageBuffer.data() + current_pos, HEADER_SIZE);
                uint32_t message_length = boost::asio::detail::socket_ops::network_to_host_long(net_length);

                size_t total_packet_size = HEADER_SIZE + message_length;

                if (m_messageBuffer.size() - current_pos >= total_packet_size) {

                    // 完整消息，提取消息体
                    Buffer message_body(
                            m_messageBuffer.begin() + current_pos + HEADER_SIZE,
                            m_messageBuffer.begin() + current_pos + total_packet_size
                    );
                    messages_out.push_back(std::move(message_body));

                    current_pos += total_packet_size;
                } else {
                    break;
                }
            }

            // 3. 清理已处理的数据
            if (current_pos > 0) {
                if (current_pos == m_messageBuffer.size()) {
                    m_messageBuffer.clear();
                } else {
                    // **【修正】使用 erase 移除已处理的部分**
                    m_messageBuffer.erase(m_messageBuffer.begin(), m_messageBuffer.begin() + current_pos);
                }
            }
            return true;
        }

        Buffer encode(const Buffer& message_body) override {
            // 编码逻辑
            uint32_t length = static_cast<uint32_t>(message_body.size());
            uint32_t net_length = boost::asio::detail::socket_ops::host_to_network_long(length);

            Buffer packet;
            packet.resize(HEADER_SIZE + length);

            // 复制头部数据
            // 使用 packet.data() 获取原始指针，注意类型是 uint8_t*
            std::memcpy(packet.data(), &net_length, HEADER_SIZE);

            // 复制消息体数据
            // message_body.data() 返回 const uint8_t*
            std::memcpy(packet.data() + HEADER_SIZE, message_body.data(), length);

            return packet;
        }

        void reset() override {
            m_messageBuffer.clear();
        }

    private:
        std::vector<uint8_t> m_messageBuffer;
    };

} // net
